[ING-DB-014] Внедрить пессимистические блокировки для транзакций цифровых семей
Обеспечение ACID-изоляции при конкурентных списаниях внутри одной виртуальной группы
- Репозиторий / Компонент:
food-ingestion-service/package postgres. - Тип задачи: Базы данных / Транзакционная целостность (Database).
- Связанные документы:
food-ingestion.qmd(Раздел 4.1 Транзакционная логика списания остатков). - Статус: Готово к реализации
Описание задачи:
Хотя цифровые семьи изолированы от реальных пользователей на уровне метаданных, внутри одной многоагентной цифровой группы (когда симулируется семья из нескольких человек) несколько параллельных воркеров симулятора могут одновременно инициировать транзакции мутации над одним виртуальным холодильником (например, одновременная готовка и потребление продуктов разными членами семьи).
Для исключения эффекта потерянных обновлений (Lost Updates) и Race Conditions на уровне шкал веса и порций PostgreSQL, необходимо перевести транзакции репозиториев с мягких инкрементов на явные пессимистические блокировки (Pessimistic Locking).
Инструкция по шагам:
Модификация транзакции Кулинарии: В методе
SaveCookingWithIngredientsрепозиторияcookingRepositoryсразу после открытия транзакцииdb.Begin(ctx)внедрить шаг пре-блокировки ресурсов. Система должна заблокировать строки ингредиентов, которые планируется списать.Реализация SELECT FOR UPDATE: Написать SQL-запрос блокировки инвентаря по составному ключу:
SELECT item_id FROM refrigerator_inventory WHERE group_id = $1 AND item_id = ANY($2) FOR UPDATE;Это заставит конкурирующие горутины, обрабатывающие действия членов одной и той же цифровой семьи, выстраиваться в строгую очередь на уровне уровня изоляции транзакций СУБД.
Интеграция с RowsAffected: Запросы
UPDATEв методеUpdateStockдолжны выполняться строго внутри этой же заблокированной транзакции, гарантируя, что проверка инварианта неотрицательного остатка основывается на монопольно захваченных данных.